package user

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/g-qs/gin-vue-admin/server/global"
	adminReq "gitee.com/g-qs/gin-vue-admin/server/model/admin/request"
	adminRes "gitee.com/g-qs/gin-vue-admin/server/model/admin/response"
	"gitee.com/g-qs/gin-vue-admin/server/model/catering"
	cateringRes "gitee.com/g-qs/gin-vue-admin/server/model/catering/response"
	"gitee.com/g-qs/gin-vue-admin/server/model/manager"
	"gitee.com/g-qs/gin-vue-admin/server/model/public"
	publicRes "gitee.com/g-qs/gin-vue-admin/server/model/public/response"
	"gitee.com/g-qs/gin-vue-admin/server/model/system"
	"gitee.com/g-qs/gin-vue-admin/server/model/user"
	userReq "gitee.com/g-qs/gin-vue-admin/server/model/user/request"
	userRes "gitee.com/g-qs/gin-vue-admin/server/model/user/response"
	//"gitee.com/g-qs/gin-vue-admin/server/service/system"
	"gitee.com/g-qs/gin-vue-admin/server/utils"
	"github.com/gofrs/uuid/v5"
	"gorm.io/gorm"
	"strconv"
	"time"
)

type UserService struct{}

//var dictionaryService = new(system.DictionaryService)

// Register 注册
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) Register(u *user.User) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		// 否则 附加uuid 密码hash加密 注册
		u.Password = utils.BcryptHash(u.Password)
		u.UUID = uuid.Must(uuid.NewV4())
		//u.UrgentCard = user.UrgentCard{}  // 创建失败了
		//u.Division = user.Division{}
		// 获取健管师信息
		var hm manager.FdHealthManager
		if hmerr := tx.Where("hm_id", u.StewardID).First(&hm).Error; hmerr != nil {
			return hmerr
		}
		// 加推广
		if u.InviteUserID == 0 { // 如果是直推
			*hm.DirectNum += 1
			if uhm := tx.Model(&manager.FdHealthManager{}).Where("hm_id", u.StewardID).Update("direct_num", *hm.DirectNum).Error; uhm != nil {
				return uhm
			}
		} else { // 如果是间推
			*hm.IndirectNum += 1
			if uhmerr := tx.Model(&manager.FdHealthManager{}).Where("hm_id", u.StewardID).Update("indirect_num", *hm.IndirectNum).Error; uhmerr != nil {
				return uhmerr
			}
		}
		// 创建User数据
		uerr := tx.Create(&u).Error
		if err != nil {
			return uerr
		}
		// 创建关联的UrgentCard数据
		urgentCard := user.UrgentCard{
			U_id: u.ID,
		}
		if ucerr := tx.Create(&urgentCard).Error; ucerr != nil {
			return ucerr
		}
		// 创建用户段位
		division := user.Division{
			ID: u.ID,
		}
		if derr := tx.Create(&division).Error; derr != nil {
			return derr
		}
		return nil
	})
}

// Login 登陆
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) Login(u *user.User) (userInter *user.User, err error) {
	if nil == global.GVA_DB {
		return nil, fmt.Errorf("db not init")
	}
	var user user.User
	err = global.GVA_DB.Where("phone = ?", u.Phone).First(&user).Error
	if err == nil {
		if ok := utils.BcryptCheck(u.Password, user.Password); !ok {
			return nil, errors.New("密码错误")
		}
	}
	return &user, err
}

// FindUserByWhere 通过条件获取单条用户信息
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) FindUserByWhere(condition map[string]interface{}, fields string) (userInfo *user.User, err error) {
	err = global.GVA_DB.Select(fields).Where(condition).Limit(1).First(&userInfo).Error
	return
}

// UpdateDataById 根据ID修改一条数据
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) UpdateDataById(ID uint, info map[string]interface{}) (err error) {
	err = global.GVA_DB.Model(&user.User{}).Where("id = ?", ID).Updates(info).Error
	return
}

// FindUserByID 通过条件获取单条用户信息
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) FindUserByID(id uint) (userInfo user.User, err error) {
	err = global.GVA_DB.Preload("UrgentCard").Preload("Division").Preload("HealthManager", func(db *gorm.DB) *gorm.DB {
		return db.Preload("HealthManageCenter", func(db *gorm.DB) *gorm.DB {
			return db.Preload("CreatorInfo")
		})
	}).First(&userInfo, id).Error
	return
}

// GetAllUserListByWhere 根据条件获取全部用户列表【超管】
func (userService *UserService) GetAllUserListByWhere(info adminReq.UserList) (list []adminRes.User, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var users []user.User
	db := global.GVA_DB.Model(&user.User{})
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.Phone != "" {
		db = db.Where("phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.InviteUserID != 0 {
		db = db.Where("invite_user_id = ?", info.InviteUserID)
	}
	if info.StewardID != 0 {
		db = db.Where("steward_id = ?", info.StewardID)
	}
	if info.InviteUserPhone != "" {
		Inviter := global.GVA_DB.Where("phone LIKE ?", "%"+info.InviteUserPhone+"%").Find(&users).Error
		if Inviter != nil {
			return nil, 0, Inviter
		}
		var ids []uint
		for _, v := range users {
			ids = append(ids, v.ID)
		}
		db = db.Where("invite_user_id IN (?)", ids)
	}
	if info.Name != "" {
		db = db.Where("name LIKE ?", "%"+info.Name+"%")
	}
	if info.Types != nil {
		db = db.Where("types = ?", info.Types)
	}
	db.Count(&total)
	//err = db.Debug().Preload("HealthManager").Preload("ProvinceInfo").Preload("CityInfo").Preload("AreaInfo").
	//	Limit(limit).Offset(offset).Find(&users).Error
	//for _, value := range users {
	//	var record user.Vip
	//	global.GVA_DB.Table("fd_vip_open_record USE INDEX (user_id)").Order("created_at DESC").First(&record, "uid = ?", value.ID)
	//	var report disease.DiseaseReportRecord
	//	global.GVA_DB.Table("fd_disease_report_record USE INDEX (uid)").Order("created_at DESC").First(&report, "uid = ?", value.ID)
	//	var tzID uint
	//	if report.TzID != 0 {
	//		tzID = report.TzID
	//	} else {
	//		tzID = 0
	//	}
	//
	//	userInfo := adminRes.User{
	//		ID:           value.ID,
	//		Points:       value.Points,
	//		InviteUserID: value.InviteUserID,
	//		StewardID:    value.HealthManager.HmId,
	//		Steward:      value.HealthManager.Name,
	//		StewardPhone: value.HealthManager.Phone,
	//		Phone:        value.Phone,
	//		Name:         value.Name,
	//		Avatar:       value.Avatar,
	//		Types:        value.Types,
	//		Sex:          value.Sex,
	//		Birthday:     value.Birthday,
	//		CreatedAt:    value.CreatedAt,
	//		ExpiredAt:    record.ExpiredAt,
	//		ReportTime:   report.CreatedAt,
	//		Physique:     tzID,
	//		ProvinceName: value.ProvinceInfo.Name,
	//		CityName:     value.CityInfo.Name,
	//		AreaName:     value.AreaInfo.Name,
	//	}
	//	list = append(list, userInfo)
	//}
	err = db.Select("fd_user.id, fd_user.points, fd_user.invite_user_id, fd_user.steward_id,fd_user.phone, fd_user.name, fd_user.avatar, fd_user.types," +
		"fd_user.sex, fd_user.birthday, fd_user.created_at," +
		"(SELECT `name` FROM fd_health_manager WHERE hm_id = fd_user.steward_id) AS steward, " +
		"(SELECT `phone` FROM fd_health_manager WHERE hm_id = fd_user.steward_id) AS stewardPhone, " +
		"(SELECT expired_at FROM fd_vip_open_record WHERE id = (SELECT MAX(id) FROM fd_vip_open_record WHERE uid = fd_user.id)) AS expiredAt," +
		"(SELECT created_at FROM fd_disease_report_record WHERE uid = fd_user.id ORDER BY created_at DESC LIMIT 1 ) AS reportTime," +
		"(SELECT tz_id FROM fd_disease_report_record WHERE uid = fd_user.id ORDER BY created_at DESC LIMIT 1) AS physique," +
		"(SELECT name FROM geo_provinces WHERE code = fd_user.province) AS province, " +
		"(SELECT name FROM geo_cities WHERE code = fd_user.city) AS city, " +
		"(SELECT name FROM geo_areas WHERE code = fd_user.area) AS area").
		Limit(limit).Offset(offset).
		Order("fd_user.id ASC").
		Scan(&list).Error
	return
}

// GetScUserListByWhere 根据条件获取服务中心用户列表【服务中心】
func (userService *UserService) GetScUserListByWhere(info adminReq.UserList, CentreID uint) (list []adminRes.User, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var users []user.User
	var serviceStations []system.SysUser
	// 获取该服务中心下的所有服务站
	if stationsErr := global.GVA_DB.Model(&system.SysUser{}).Where("authority_id = ? AND creator = ?", 444, CentreID).Find(&serviceStations).Error; stationsErr != nil {
		return nil, 0, stationsErr
	}
	var ids []uint
	for _, v := range serviceStations {
		ids = append(ids, v.ID)
	}
	db := global.GVA_DB.Model(&user.User{}).Where("service_center_id IN (?)", ids)
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.Phone != "" {
		db = db.Where("phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.InviteUserID != 0 {
		db = db.Where("invite_user_id = ?", info.InviteUserID)
	}
	if info.StewardID != 0 {
		db = db.Where("steward_id = ?", info.StewardID)
	}
	if info.InviteUserPhone != "" {
		Inviter := global.GVA_DB.Where("phone LIKE ?", "%"+info.InviteUserPhone+"%").Find(&users).Error
		if Inviter != nil {
			return nil, 0, Inviter
		}
		var IDs []uint
		for _, v := range users {
			IDs = append(ids, v.ID)
		}
		db = db.Where("invite_user_id IN (?)", IDs)
	}
	if info.Name != "" {
		db = db.Where("name LIKE ?", "%"+info.Name+"%")
	}
	if info.Types != nil {
		db = db.Where("types = ?", info.Types)
	}
	db.Count(&total)
	err = db.Select("fd_user.id, fd_user.points, fd_user.invite_user_id, fd_user.steward_id,fd_user.phone, fd_user.name, fd_user.avatar, fd_user.types," +
		"fd_user.sex, fd_user.birthday, fd_user.created_at," +
		"(SELECT `name` FROM fd_health_manager WHERE hm_id = fd_user.steward_id) AS steward, " +
		"(SELECT `phone` FROM fd_health_manager WHERE hm_id = fd_user.steward_id) AS stewardPhone, " +
		"(SELECT expired_at FROM fd_vip_open_record WHERE id = (SELECT MAX(id) FROM fd_vip_open_record WHERE uid = fd_user.id)) AS expiredAt," +
		"(SELECT created_at FROM fd_disease_report_record WHERE uid = fd_user.id ORDER BY created_at DESC LIMIT 1 ) AS reportTime," +
		"(SELECT tz_id FROM fd_disease_report_record WHERE uid = fd_user.id ORDER BY created_at DESC LIMIT 1) AS physique," +
		"(SELECT name FROM geo_provinces WHERE code = fd_user.province) AS province, " +
		"(SELECT name FROM geo_cities WHERE code = fd_user.city) AS city, " +
		"(SELECT name FROM geo_areas WHERE code = fd_user.area) AS area").
		Limit(limit).Offset(offset).
		Order("fd_user.id ASC").
		Scan(&list).Error
	return
}

// GetUserInfo 获取用户信息
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) GetUserInfo(uuid uuid.UUID) (info userRes.UserInfo, err error) {
	var userInfo user.User
	err = global.GVA_DB.Model(&user.User{}).Where("uuid = ?", uuid).Preload("UrgentCard").Find(&userInfo).Error
	var vip user.Vip
	vipInfo := global.GVA_DB.Select("created_at,expired_at,status,apply_for_at").Where("uid = ?", userInfo.ID).Order("created_at Desc").Limit(1).First(&vip).Error
	if errors.Is(vipInfo, gorm.ErrRecordNotFound) {
		// 这段其实没啥用 不校验error就好了 错误了的话 vip ExpiredAt 和  Status 会是默认值
		vip.ExpiredAt = nil
		vip.Status = 1
	}
	info = userRes.UserInfo{
		ID:              userInfo.ID,
		ServiceCenterID: userInfo.ServiceCenterID,
		StewardID:       userInfo.StewardID,
		InviteUserID:    userInfo.InviteUserID,
		Phone:           userInfo.Phone,
		Name:            userInfo.Name,
		Avatar:          userInfo.Avatar,
		Types:           userInfo.Types,
		Sex:             userInfo.Sex,
		Birthday:        userInfo.Birthday,
		Province:        userInfo.Province,
		City:            userInfo.City,
		Area:            userInfo.Area,
		Addr:            userInfo.Addr,
		Contact:         userInfo.UrgentCard.Contact,
		ContactPhone:    userInfo.UrgentCard.ContactPhone,
		ApplyForAt:      vip.ApplyForAt,
		ExpiredAt:       vip.ExpiredAt,
		Status:          vip.Status,
		Points:          userInfo.Points,
	}
	return info, err
}

// UpdateUser 更新用户信息
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) UpdateUser(id uint, ur userReq.UpdateUser) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var su user.User
		userInfo := user.User{
			Name:     ur.Name,
			Avatar:   ur.Avatar,
			Sex:      ur.Sex,
			Birthday: ur.Birthday,
			Province: ur.Province,
			City:     ur.City,
			Area:     ur.Area,
			Addr:     ur.Addr,
		}
		err := tx.First(&su, id).Updates(userInfo).Error
		if err != nil {
			return err
		}
		urgentCard := user.UrgentCard{
			Contact:      ur.Contact,
			ContactPhone: ur.ContactPhone,
		}
		err = tx.First(&user.UrgentCard{}, id).Updates(urgentCard).Error
		if err != nil {
			return err
		}
		return nil
	})
}

// ChangePassword 修改用户密码
func (userService *UserService) ChangePassword(id uint, newPassword string) (err error) {
	Password := utils.BcryptHash(newPassword)
	if err = global.GVA_DB.Model(&user.User{}).Where("id = ?", id).Update("password", Password).Error; err != nil {
		return err
	}
	return nil
}

// FindLastRecordByWhere 获取最近记录
func (userService *UserService) FindLastRecordByWhere(id uint) (vip user.Vip, err error) {
	err = global.GVA_DB.Select("expired_at,status").Where("uid = ?", id).Order("created_at Desc").Limit(1).First(&vip).Error
	return
}

// GetRecordBy 获取最近记录
func (userService *UserService) GetRecordBy(id uint) (vip user.Vip, err error) {
	err = global.GVA_DB.Preload("User").Where("id = ?", id).First(&vip).Error
	return
}

// GetOpenVipRecord 获取开通会员记录
func (userService *UserService) GetOpenVipRecord(info adminReq.OpenVipSearch, userID uint) (list []user.Vip, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&user.Vip{}).Preload("User").Joins("User")
	var openRecord []user.Vip
	// 如果有条件搜索 下方会自动创建搜索语句
	db = db.Where("User.steward_id = ?", userID)
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.UserName != "" {
		db = db.Where("User.name LIKE ?", "%"+info.UserName+"%")
	}
	if info.Phone != "" {
		db = db.Where("User.phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.Status == 2 {
		db = db.Where(user.Vip{}.TableName()+".status = ?", 2)
	} else {
		db = db.Where(user.Vip{}.TableName()+".status != ?", 2)
	}
	err = db.Count(&total).Error
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	// 处理数据
	err = db.Order("created_at DESC").Find(&openRecord).Error
	return openRecord, total, err
}

// GetServiceStationOpenVipRecord 获取服务站开通会员记录
func (userService *UserService) GetServiceStationOpenVipRecord(info adminReq.OpenVipSearch, userID uint) (list []user.Vip, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&user.Vip{}).Preload("User")
	var openRecord []user.Vip
	var users []user.User
	// 查询所有服务站用户
	if usersErr := global.GVA_DB.Where("service_center_id = ?", userID).Find(&users).Error; usersErr != nil {
		return list, total, usersErr
	}
	var userIDs []uint
	for _, userValue := range users {
		userIDs = append(userIDs, userValue.ID)
	}
	// 如果有条件搜索 下方会自动创建搜索语句
	db = db.Where("uid IN (?)", userIDs)
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.UserName != "" {
		Inviter := global.GVA_DB.Where("name LIKE ?", "%"+info.UserName+"%").Find(&users).Error
		if Inviter != nil {
			return nil, 0, Inviter
		}
		var ids []uint
		for _, v := range users {
			ids = append(ids, v.ID)
		}
		db = db.Where("uid IN (?)", ids)
	}
	if info.Phone != "" {
		Inviter := global.GVA_DB.Where("phone LIKE ?", "%"+info.Phone+"%").Find(&users).Error
		if Inviter != nil {
			return nil, 0, Inviter
		}
		var ids []uint
		for _, v := range users {
			ids = append(ids, v.ID)
		}
		db = db.Where("uid IN (?)", ids)
	}
	if info.Status == 2 {
		db = db.Where(user.Vip{}.TableName()+".status = ?", 2)
	} else {
		db = db.Where(user.Vip{}.TableName()+".status != ?", 2)
	}
	err = db.Count(&total).Error
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	// 处理数据
	err = db.Order("created_at DESC").Find(&openRecord).Error
	return openRecord, total, err
}

// GetAllOpenVipRecord 获取全部开通会员记录【超管】
func (userService *UserService) GetAllOpenVipRecord(info adminReq.OpenVipSearch) (list []user.Vip, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var users []user.User
	// 创建db
	db := global.GVA_DB.Model(&user.Vip{}).Preload("User")
	var openRecord []user.Vip
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.UserName != "" {
		Inviter := global.GVA_DB.Where("name LIKE ?", "%"+info.UserName+"%").Find(&users).Error
		if Inviter != nil {
			return nil, 0, Inviter
		}
		var ids []uint
		for _, v := range users {
			ids = append(ids, v.ID)
		}
		db = db.Where("uid IN (?)", ids)
	}
	if info.Phone != "" {
		Inviter := global.GVA_DB.Where("phone LIKE ?", "%"+info.Phone+"%").Find(&users).Error
		if Inviter != nil {
			return nil, 0, Inviter
		}
		var ids []uint
		for _, v := range users {
			ids = append(ids, v.ID)
		}
		db = db.Where("uid IN (?)", ids)
	}
	if info.Status == 2 {
		db = db.Where(user.Vip{}.TableName()+".status = ?", 2)
	} else {
		db = db.Where(user.Vip{}.TableName()+".status != ?", 2)
	}
	err = db.Count(&total).Error
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	// 处理数据
	err = db.Order("created_at DESC").Find(&openRecord).Error
	return openRecord, total, err
}

// CreateOpenRecord 创建开通记录
func (userService *UserService) CreateOpenRecord(id uint) (err error) {
	// 用户创建开通记录时候就会进入待审核状态 然后等待管理员审核
	vip := user.Vip{
		Uid:        id,
		CreatedAt:  time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Now().Location()),
		UpdatedAt:  time.Now(),
		ExpiredAt:  nil,
		ApplyForAt: time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Now().Location()),
		VipType:    0,
		Status:     1,
	}

	if err := global.GVA_DB.Create(&vip).Error; err != nil {
		return err
	}
	return
}

// GetUserByVipLevel 通过会员等级获取用户信息
func (userService *UserService) GetUserByVipLevel(vip_type string) (err error) {
	var vips []user.Vip
	// 用户创建开通记录时候就会进入待审核状态 然后等待管理员审核
	_ = global.GVA_DB.Preload("User").Group("uid").Order("created_at desc").Find(&vips, "vip_type = ? and status = ?", vip_type, 2).Error

	var vips2 []user.Vip

	_ = global.GVA_DB.Preload("User").Joins("User").Group("uid").Order("created_at desc").Find(&vips2, "vip_type = ? and fd_vip_open_record.status = ? and User.Phone LIKE ?", vip_type, 2, "%135%").Error

	return
}

// UpdateOpenRecord 修改开通记录
func (userService *UserService) UpdateOpenRecord(id, status, vipType string) (err error) {
	//管理审核状态，如果状态为通过，那么表示付费了，这时候修改过期时间和status即可
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var vipInfo user.Vip
		var expiredAt time.Time
		var userInfo user.User
		if err = tx.First(&vipInfo, "id = ?", id).Update("status", status).Update("vip_type", vipType).Error; err != nil {
			return err
		}
		if status == "2" {
			//如果是通过状态，那么就需要修改过期时间
			var vipDict system.SysDictionary
			//获取会员类型
			vDErr := global.GVA_DB.Where("type = ?", "vip").Preload("SysDictionaryDetails", func(db *gorm.DB) *gorm.DB {
				return db.Where("status = ?", true).Order("sort")
			}).First(&vipDict).Error
			//vipDict, vDErr := dictionaryService.GetSysDictionary("vip", 0, nil)
			if vDErr != nil {
				return vDErr
			}
			for i := range vipDict.SysDictionaryDetails {
				if vipDict.SysDictionaryDetails[i].Value == vipType {
					day, dErr := strconv.Atoi(vipDict.SysDictionaryDetails[i].Extend)
					if dErr != nil {
						return dErr
					}
					expiredAt = time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Now().Location()).AddDate(0, 0, day)
				}
			}
			//var applyForAt *time.Time
			if uPErr := tx.First(&userInfo, "id = ?", vipInfo.Uid).Update("types", 2).Error; uPErr != nil {
				return uPErr
			}
			//if upDErr := tx.First(&vipInfo, "id = ?", id).Updates(map[string]interface{}{"expired_at": expiredAt, "apply_for_at": applyForAt}).Error; upDErr != nil {
			//	return upDErr
			//}
			if upDErr := tx.First(&vipInfo, "id = ?", id).Updates(map[string]interface{}{"expired_at": expiredAt}).Error; upDErr != nil {
				return upDErr
			}
		}
		return nil
	})
}

// GetUserDivisionInfo 获取用户成就
func (userService *UserService) GetUserDivisionInfo(id uint) (info cateringRes.UserDivisionInfo, err error) {
	//var userinfo user.User
	var userDivision user.Division
	var records []catering.PlanCompleteRecord
	var count int64
	// 获取用户直推人数
	err = global.GVA_DB.Model(&user.User{}).Where("invite_user_id = ?", id).Count(&count).Error
	// 获取用户成就信息
	err = global.GVA_DB.Model(&user.Division{}).Where("id = ?", id).First(&userDivision).Error
	// 获取用户一周内的签到记录
	err = global.GVA_DB.Where("created_at BETWEEN ? AND ?", time.Now().AddDate(0, 0, -6), time.Now()).Order("created_at ASC").Find(&records).Error
	var WeekSchedules []cateringRes.WeekSchedule
	currentDate := time.Now()
	startDate := currentDate.AddDate(0, 0, -int(currentDate.Weekday())+1)
	for i := 0; i < 7; i++ {
		// Calculate the date of the current day
		currentDate := startDate.AddDate(0, 0, i)
		status := false
		for _, record := range records {
			if record.CreatedAt.Day() == currentDate.Day() {
				status = true
				break
			}
		}
		WeekSchedules = append(WeekSchedules, cateringRes.WeekSchedule{
			Status: status,
			Key:    currentDate.Day(),
			Week:   currentDate.Weekday(),
		})
	}
	info = cateringRes.UserDivisionInfo{
		PromotionNumber: count,
		Division: cateringRes.DivisionNumber{
			Bronze: userDivision.Bronze,
			Silver: userDivision.Silver,
			Gold:   userDivision.Gold,
		},
		Data: WeekSchedules,
	}
	return
}

// GetUserDivisionRank 获取用户段位排行榜
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) GetUserDivisionRank() (Info []public.UserDivisionRank, err error) {
	//var users []user.User
	err = global.GVA_DB.Table("fd_user").
		Select("fd_user.id, fd_user.name, fd_user.avatar, fd_user_division.bronze, fd_user_division.silver, fd_user_division.gold").
		Joins("LEFT JOIN fd_user_division ON fd_user.id = fd_user_division.id").
		Order("fd_user_division.bronze + fd_user_division.silver + fd_user_division.gold DESC").
		Find(&Info).Error
	//for _, v := range users {
	//	Info = append(Info, public.UserDivisionRank{
	//		Id:     v.ID,
	//		Name:   v.Name,
	//		Avatar: v.Avatar,
	//		Bronze: v.Division.Bronze,
	//		Silver: v.Division.Silver,
	//		Gold:   v.Division.Gold,
	//	})
	//}
	return Info, err
}

// AddPoints 添加积分
// Author: [g-qs](https://github.com/g-qs)
func (userService *UserService) AddPoints(uid, points, types uint) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var msg string
		if types == 1 {
			msg = "今日点赞"
		} else if types == 2 {
			msg = "今日评论"
		} else if types == 3 {
			msg = "方案完成"
		} else if types == 4 {
			msg = "今日发健康圈全部"
		} else if types == 5 {
			msg = "完善个人资料"
		} else if types == 6 {
			msg = "邀请新人"
		} else if types == 7 {
			msg = "采纳建议"
		}
		// 检查是否满足获取积分条件
		if !checkPointConditions(uid, types) {
			return errors.New("已领取" + msg + "奖励积分")
		}
		pointsRecord := public.Points{
			Uid:       uid,
			Types:     types,
			CreatedAt: time.Now(),
			Points:    points,
		}
		if err := tx.Create(&pointsRecord).Error; err != nil {
			return err
		}
		if err := tx.Model(&user.User{}).Where("ID = ?", uid).Update("points", gorm.Expr("points + ?", points)).Error; err != nil {
			return err
		}
		// 更新缓存
		updatePointConditions(uid, types)
		return nil
	})
}

// GetCountWeeklyPoints 获取用户一周积分
func (userService *UserService) GetCountWeeklyPoints(UserID uint) (list []publicRes.WeekPointsData, err error) {
	var pw []publicRes.PointsWithTotal
	err = global.GVA_DB.
		Select("COALESCE(SUM(points), 0) as total_points, DATE(created_at) as created_at").
		Where("uid = ? AND created_at BETWEEN ? AND ?", UserID, time.Now().AddDate(0, 0, -6), time.Now()).
		Group("DATE(created_at)"). // 根据日期分组
		Order("created_at ASC").
		Find(&pw).Error
	if err != nil {
		panic("查询失败")
	}
	// 构建每天的积分数据
	for i := 1; i < 8; i++ {
		startOfWeek := time.Now().AddDate(0, 0, -int(time.Now().Weekday())+i)
		var totalPoints uint
		isToday := false

		// 在查询到的积分记录中找到今天的数据
		for _, v := range pw {
			if v.CreatedAt.Day() == startOfWeek.Day() {
				isToday = true
				totalPoints = v.TotalPoints
				break
			}
		}

		// 构建数据
		dayData := publicRes.WeekPointsData{
			Points:  totalPoints,
			Key:     startOfWeek.Day(),
			Week:    i,
			IsToday: isToday,
		}
		list = append(list, dayData)
	}
	return
}

// checkPointConditions 检查用户是否满足获取积分
func checkPointConditions(userID uint, pointType uint) bool {
	switch pointType {
	case 1:
		// 点赞
		return checkDailyLimit(userID, "Like", 5)
	case 2:
		// 评论
		return checkDailyLimit(userID, "Comment", 5)
	case 3:
		// 方案执行
		return checkDailyLimit(userID, "CompleteScheme", 1)
	case 4:
		// 发健康圈
		return checkDailyLimit(userID, "Publish", 5)
	case 5:
		// 完善个人资料
		return checkOneTimeLimit(userID, "PerfectData")
	case 6:
		// 邀请好友
		return true // 不受限制
	default:
		return false
	}
}

// checkOneTimeLimit 根据条件查询每日限制
func checkDailyLimit(userID uint, pointType string, maxActionsPerDay int) bool {
	key := fmt.Sprintf("UserPointLimit:%d:%s", userID, pointType)
	val, _ := global.GVA_REDIS.Get(context.Background(), key).Int()
	// 当限制缓存不存在
	expirationTime := time.Until(time.Now().Add(24 * time.Hour)).Round(time.Second)
	if val == 0 {
		global.GVA_REDIS.Set(context.Background(), key, "1", expirationTime)
		return true
	} else {
		if val > maxActionsPerDay { // 超过每日最大次数限制
			return false
		} else {
			return true
		}
	}
}

// checkOneTimeLimit 检查一次性限制条件
func checkOneTimeLimit(userID uint, pointType string) bool {
	key := fmt.Sprintf("UserPointLimit:%d:%s", userID, pointType)
	val, _ := global.GVA_REDIS.Get(context.Background(), key).Result()
	if val != "" {
		return false // 已获得过积分，不再允许
	}
	return true
}

// updatePointConditions 更新用户获取积分的限制Redis
func updatePointConditions(userID uint, pointType uint) {
	// 在这个示例中，仅用于一次性限制条件的情况下更新Redis中的键值
	// 实际应用中，可以根据具体需求添加其他情况下的更新逻辑
	var Type string
	if pointType == 1 {
		Type = "Like"
		key := fmt.Sprintf("UserPointLimit:%d:%s", userID, Type)
		global.GVA_REDIS.Incr(context.Background(), key)
	} else if pointType == 2 {
		Type = "Comment"
		key := fmt.Sprintf("UserPointLimit:%d:%s", userID, Type)
		global.GVA_REDIS.Incr(context.Background(), key)
	} else if pointType == 3 {
		Type = "CompleteScheme"
		key := fmt.Sprintf("UserPointLimit:%d:%s", userID, Type)
		global.GVA_REDIS.Incr(context.Background(), key)
	} else if pointType == 4 {
		Type = "Publish"
		key := fmt.Sprintf("UserPointLimit:%d:%s", userID, Type)
		global.GVA_REDIS.Incr(context.Background(), key)
	} else if pointType == 5 {
		Type = "PerfectData"
		key := fmt.Sprintf("UserPointLimit:%d:%s", userID, Type)
		global.GVA_REDIS.Incr(context.Background(), key)
	}
}

// GetOneAllRedisById 获取用户信息
func (userService *UserService) GetOneAllRedisById(id uint) (userInfo user.User, err error) {
	idStr := strconv.Itoa(int(id))
	key := "User:ID:" + idStr
	isExists, _ := global.GVA_REDIS.Exists(context.Background(), key).Result()
	if isExists == 0 { // 如果不存在缓存
		err = global.GVA_DB.Model(&user.User{}).Where("id = ?", idStr).Preload("UrgentCard").Preload("Vip").Find(&userInfo).Error
		if err != nil {
			return
		}
		// 组装用户信息
		userInfo = user.User{
			GVA_MODEL: global.GVA_MODEL{
				ID: userInfo.ID,
			},
			UUID:            userInfo.UUID,
			ServiceCenterID: userInfo.ServiceCenterID,
			StewardID:       userInfo.StewardID,
			InviteUserID:    userInfo.InviteUserID,
			Phone:           userInfo.Phone,
			Password:        userInfo.Password,
			Name:            userInfo.Name,
			Avatar:          userInfo.Avatar,
			Types:           userInfo.Types,
			Sex:             userInfo.Sex,
			Birthday:        userInfo.Birthday,
			Province:        userInfo.Province,
			City:            userInfo.City,
			Area:            userInfo.Area,
			Addr:            userInfo.Addr,
			UrgentCard: user.UrgentCard{
				Contact:      userInfo.UrgentCard.Contact,
				ContactPhone: userInfo.UrgentCard.ContactPhone,
			},
		}
		jsonData, err := json.Marshal(userInfo)
		if err != nil {
			return userInfo, err
		}
		err = global.GVA_REDIS.HSet(context.Background(), key, "data", jsonData).Err()
		if err != nil {
			return userInfo, err
		}
		// 设置过期时间，例如 24 小时
		err = global.GVA_REDIS.Expire(context.Background(), key, 14*24*time.Hour).Err()
		if err != nil {
			return userInfo, err
		}
	}
	val, err := global.GVA_REDIS.HGet(context.Background(), key, "data").Result()
	if err == nil {
		// 在缓存中找到用户信息，解析并返回
		err = json.Unmarshal([]byte(val), &userInfo)
	}
	return userInfo, err
}

// CalculateAge 计算年龄
func (userService *UserService) CalculateAge(birthdate time.Time) uint {
	now := time.Now()
	years := uint(now.Year() - birthdate.Year())
	if now.YearDay() < birthdate.YearDay() {
		years--
	}
	return years
}

// TranslateTable 创建开通记录
func (userService *UserService) TranslateTable() (err error) {
	var OldUsers []user.OldUser
	// 用户创建开通记录时候就会进入待审核状态 然后等待管理员审核
	_ = global.GVA_DB.Find(&OldUsers).Error
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		for i := range OldUsers {
			newUser := user.User{
				//ID:    OldUsers[i].ID,
				//UUID:  uuid.Must(uuid.NewV4()),
				//Phone: OldUsers[i].Phone,
				UUID:            uuid.Must(uuid.NewV4()),
				ServiceCenterID: 1, // 服务中心给谁
				StewardID:       1, // 健管师给谁
				Phone:           OldUsers[i].Phone,
				Name:            OldUsers[i].Nick,
				Sex:             uint(OldUsers[i].Sex),
				Password:        utils.BcryptHash(OldUsers[i].Phone),
				UrgentCard:      user.UrgentCard{},
				Division:        user.Division{},
			}
			err = global.GVA_DB.Create(&newUser).Error
			fmt.Sprintf("%s正在迁移", newUser.Name)
			if err != nil {
				return err
			}
		}
		return nil
	})
}

// GetPromotionUserList 获取推广用户[健管师]
func (userService *UserService) GetPromotionUserList(info userReq.PromotionUserSearch) (list []userRes.PromotionUser, err error) {
	db := global.GVA_DB.Model(&user.User{}).Select("fd_user.id, fd_user.name, fd_user.phone, fd_user.types, fd_vip_open_record.expired_at").
		Joins("LEFT JOIN fd_vip_open_record ON fd_user.id = fd_vip_open_record.uid").Where("fd_user.steward_id = ?", info.StewardID)
	if info.Name != "" {
		db = db.Where("fd_user.name LIKE ?", "%"+info.Name+"%")
	}
	if info.Phone != "" {
		db = db.Where("fd_user.phone LIKE ?", "%"+info.Phone+"%")
	}
	err = db.Group("fd_user.id").Order("fd_vip_open_record.expired_at DESC").Find(&list).Error
	return
}
